#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>

#include "Object3D.h"
#include "Vertex3D.h"
#include "Triangle.h"
#include "Scene.h"
#include "Camera.h"


using namespace std;

Object3D *obja;
Object3D *objb;

GLuint n1, n2;

GLdouble pos[3]={0.0, 1.0, 6.0};
GLdouble look[3]={0.0, 1.0, 0.0};
GLdouble up[3]={0.0, 1.0, 0.0};

Camera  *cam=new Camera(pos, look, up);

Scene *sc=new Scene(cam);

Object3D *
read_orj (const char *path);

void
draw_screen ()
{
	glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
		
	sc->draw ();
	
	SDL_GL_SwapBuffers ();

}
void
initGL (int w, int h)
{
  glViewport(0, 0, w, h);
  glClearColor(0.2, 0.2, 0.2, 0.0);
  glColor3f(1.0, 1.0, 1.0);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);
  
  // Enable basic lighting.
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
  
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 1.0, 10.0);
  glMatrixMode(GL_MODELVIEW);
  glEnable(GL_DEPTH_TEST);
 	 
}

static SDL_Surface*
initSDL
(int w, int h, const char *caption)
{
  SDL_Surface* sf = 0;

  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    cerr << "SDL_Init: " << SDL_GetError() << endl;
    return 0;
  }

  // Activate double buffering.
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

  sf = SDL_SetVideoMode(w, h, 16, SDL_OPENGL | SDL_DOUBLEBUF | SDL_HWSURFACE );
  if (sf == 0) {
    cerr << "SDL_SetVideoMode: " << SDL_GetError() << endl;
    SDL_Quit();
    return 0;
  }

  SDL_WM_SetCaption(caption, 0);

  // Initialize OpenGL.
  initGL(w, h);

  return sf;
}

int
main
(int argc, char ** argv)
{
  bool done;

  SDL_Surface *sf = initSDL (640, 480, "Test");
	
  SDL_Event event;

  done = false;
	
	obja = read_orj ("./mono.orj");
	objb = read_orj("./piramid.orj");
	
	sc->add_object(obja);
	sc->add_object(objb);
	sc->merge(0,1);

	Vertex3D point (objb->get_com ());
	point.set_x(point.x()+5);
	objb->move(point);
	while (!done) 
		{
			if (SDL_PollEvent(&event)) 
				{
					if (event.type == SDL_QUIT) 
						done = true;
				}
			else if (event.type == SDL_KEYDOWN) 
				{
					uint32_t sym = event.key.keysym.sym;

					switch (sym) 
						{
							case SDLK_a:
								point.set_x(point.x()-0.1);
								obja->move(point);
								break;
							case SDLK_d:
								point.set_x(point.x()+0.1);
								obja->move(point);
								break;
							case SDLK_w:
								point.set_y(point.y()+0.1);
								obja->move(point);
								break;
							case SDLK_s:
								point.set_y(point.y()-0.1);
								obja->move(point);
								break;
							case SDLK_r:
								point.set_z(point.z()+0.1);
								obja->move(point);
								break;
							case SDLK_f:
								point.set_z(point.z()-0.1);
								obja->move(point);
								break;
							case SDLK_m:
								obja->scale (1.1, X);
								break;
							case SDLK_l:
								obja->scale (0.9, X);
								break;
							case SDLK_u:
								obja->rotate (1, X);
								break;
							case SDLK_i:
								obja->rotate (-1, X);
								break;
							case SDLK_o:
								sc->merge(n1, n2);
						}
				}
			draw_screen();
		}	
  SDL_Quit ();

  return 0;
}
